<?php
// KERNEL BEGIN
$_SYS['meccano']['version']  = '0.2.21';
$_SYS['meccano']['serial']   = 20080214;
$_SYS['meccano']['session']  = 'meccano';
$_SYS['meccano']['debugtpl'] = 1; # Turn On/Off debugin of Templates

require_once(dirname(__FILE__) . '/config.inc');

// DEFINE PATHES
if(!defined("LIB_REL"))   define("LIB_REL", $lib_path);
if(!defined("TEMPLATES")) define("TEMPLATES", $tpl_path);
if(!defined("ROOT"))
{
   $root = $_SERVER['DOCUMENT_ROOT'];
   if(substr($root, -1, 1) == '/') $root = substr($root, 0, -1);
   define("ROOT", $root);
}
if(!defined("LIBRARIES")) define("LIBRARIES", ROOT.$lib_path);
if(!defined("HOSTNAME"))  define("HOSTNAME", "http://".$_SERVER['HTTP_HOST']);

// DECLARATION OF VARIABLES
$action   = false;
$id       = false;
$moduleid = false;
$category = false;
$lang     = false;
$error    = false;
$make     = false;
$event    = false;

require_once(LIBRARIES.'/functions.inc');

/*  check ID variable  */
if(isset($_REQUEST['id']))
{
   $id = $_REQUEST['id'];
   isDigit($id);
   unset($_REQUEST['id']);
}

/*  check CAT (category) variable  */
if(isset($_REQUEST['cat']))
{
   isDigit($_REQUEST['cat']);
   $category = $_REQUEST['cat'];
   unset($_REQUEST['cat']);
}
$cat = &$category;

/*  check A (action) variable  */
if(isset($_REQUEST['a']))
{
   isDigit($_REQUEST['a']);
   if($_REQUEST['a'] != false) $action = $_REQUEST['a'];
   unset($_REQUEST['a']);
}

/*  check SUBMIT variable  */
if(isset($_REQUEST['submit']))
{
   $submit = true;
   unset($_REQUEST['submit']);
} else
{
   $submit = false;
}

/*  Init DB class and Connect to DB  */
require_once(LIBRARIES.'/db.class.inc');
$DB = new DB_SQL($db_host, $db_name, $db_user, $db_pass);
$DB->sql = "SET NAMES utf8";
$DB->DB_Query();

/*  Init MECCANO class  */
require_once(LIBRARIES.'/meccano.inc');
$MECCANO = new meccano($DB);

/*  Init AUTHorization class  */
require_once(LIBRARIES.'/auth.class.inc');
$AUTH = new Users($_SYS['meccano']['session'], $MECCANO->system['auth_live'], $DB);


/*  check LANG variable  */
if(isset($_REQUEST['lang']) && in_array($_REQUEST['lang'], $MECCANO->system['lang']))
{
   $lang = $_REQUEST['lang'];
} elseif(isset($_SESSION['lang']))
{
   $lang = $_SESSION['lang'];
} else
{
   $lang = $MECCANO->system['lang'][0];
}
$_SESSION['lang'] = $lang;
unset($_REQUEST['lang']);

/*  check EVENT variable  */
if(isset($_REQUEST['e']) && isset($MECCANO->events[$_REQUEST['e']]))
{
   $event = $_REQUEST['e'];
   unset($_REQUEST['e']);
}

/*  check MODULE variable  */
if(isset($_REQUEST['m']))
{
   $moduleid = isDigit($_REQUEST['m']);
   unset($_REQUEST['module']);
} elseif(isset($_SESSION['moduleid']))
{
   $moduleid = $_SESSION['moduleid'];
}
$_SESSION['moduleid'] = $moduleid;
if($moduleid)
{
   $module = $MECCANO->kernel[$moduleid];
} else
{
   $module = false;
}

$pid                         = basename($_SERVER['PHP_SELF']);
if($id !== false)       $pid = $pid.$id;
if($category !== false) $pid = $pid.$category;
if($action !== false)   $pid = $pid.$action;
if($lang != false)      $pid = $pid.$lang;
if($event != false)     $pid = $pid.$event;
$_SYS['meccano']['pid']      = md5($pid);
unset($pid);
$pid = &$_SYS['meccano']['pid'];


require_once(LIBRARIES.'/smarty/Smarty.class.php');
require_once(LIBRARIES.'/smarty/SmartyPaginate.class.php');
$SMARTY = new Smarty();
$SMARTY->template_dir = ROOT.TEMPLATES;
$SMARTY->compile_dir = ROOT.$compiled_tpl_path;
$SMARTY->cache_dir = ROOT.$cache_path;
$SMARTY->left_delimiter = '{%';
$SMARTY->right_delimiter = '%}';
$SMARTY->caching = $MECCANO->system['caching'];
$SMARTY->debugging = $_SYS['meccano']['debugtpl'];
$SMARTY->assign_by_ref('meccano', $MECCANO->system);
$SMARTY->assign_by_ref('events', $MECCANO->events);
$SMARTY->assign_by_ref('make', $make);
$SMARTY->assign_by_ref('error', $error);
$SMARTY->assign('templates', TEMPLATES);
$SMARTY->assign('library',LIB_REL);
$SMARTY->assign('url', HOSTNAME);
$SMARTY->assign_by_ref('id', $id);
$SMARTY->assign_by_ref('action', $action);
$SMARTY->assign_by_ref('category', $category);
$SMARTY->assign_by_ref('sysadminname', $MECCANO->system['admin_name']);
$SMARTY->assign_by_ref('sysadminmail', $MECCANO->system['admin_email']);
$SMARTY->assign_by_ref('version', $_SYS['meccano']['version']);
$SMARTY->assign_by_ref('pid', $_SYS['meccano']['pid']);
$SMARTY->assign_by_ref('langs', $MECCANO->system['lang']);
$SMARTY->assign_by_ref('lang', $lang);

SmartyPaginate::connect($_SYS['meccano']['pid']);
SmartyPaginate::setLimit($MECCANO->system['items'], $_SYS['meccano']['pid']);
SmartyPaginate::setPageLimit($MECCANO->system['pages'], $_SYS['meccano']['pid']);




/*
 * SWITCH MAIN KERNEL CLASS TO PHP VERSION
 */
class Kernel_PHP5 extends kern
{
    function __call($method, $params)
    {
        // do something
    }
}


class Kernel_PHP4 extends kern
{
    function __call__($method, $params)
    {
        // do something
    }
}


/**
 * MAIN KERNEL CLASS
 */

class kern
{
   var $DB       = null;
   var $MECCANO  = null;
   var $GALLERY  = null;
   var $CAL      = null;
   var $error    = false;
   var $property = false;
   var $moduleid = null;
   var $params   = array();
   var $table    = null;


   /**
    * Constructor of KERNEL
    *
    * @param integer $module
    */
   function __construct($module = false)
   {
      $this->error = false;

      if(isset($GLOBALS['DB']))
      {
         $this->DB = &$GLOBALS['DB'];
      } else
      {
         $this->error['system'][] = "No DateBase Object registered!";
      }

      if(isset($GLOBALS['MECCANO']))
      {
         $this->MECCANO = &$GLOBALS['MECCANO'];
      } else
      {
         $this->error['system'][] = "No MECCANO Object registered!";
      }

      if(isDigit($module))
      {
         $this->moduleid = $module;
      } else
      {
         $this->error['system'][] = 'Which module?';
      }

      $this->property['table']      = &$this->MECCANO->kernel[$this->moduleid]['table'];
      $this->property['treedepend'] = &$this->MECCANO->kernel[$this->moduleid]['treedepend'];
      $this->property['userdepend'] = &$this->MECCANO->kernel[$this->moduleid]['userdepend'];
      $this->property['gallery']    = &$this->MECCANO->kernel[$this->moduleid]['gallery'];
      $this->property['calendar']   = &$this->MECCANO->kernel[$this->moduleid]['calendar'];

      $this->SetParams();
   }


   /**
    * Constructor for PHP4
    *
    * @param unknown_type $module
    */
   function kernel($module = false)
   {
      $this->__construct($module);
   }


   /**
    * Set $this->params for DATA handling
    * params separated by semicolon (;)
    * var name separated from var value by (=)
    * value as array can be passed with comma (,)
    *
    * @param string $params
    * @return bool
    */
   function SetParams($params = 'clear')
   {
      if($params == 'clear')
      {
         $this->params['mode']          = 'i';
         $this->params['sort']          = ' ASC';
         $this->params['language']      = null;
         $this->params['default_lang']  = $this->MECCANO->system['lang']['0'];
         $this->params['all_langs']     = false;
         $this->params['user']          = 0;  // 0 - Virtual User, Can See all, but Do nothing
         $this->params['search_length'] = 64;
         $this->params['hidden']        = false;
         $this->params['indate']        = false;
         $this->params['count_views']   = true;
         $this->params['relate_table']  = false;
         $this->params['tie_fields']    = false;
         $this->params['topsite']       = false;
         return true;
      }

      $params = explode(';', $params);

      $modes = array(
      'i', // as Inputed
      't', // by Title
      'd', // by Date
      's', // in current date
      'k', // in cureent date, if false by random
      'c', // by Category
      'r'  // Random
      );

      foreach ($params as $value)
      {
         $p = explode('=', $value);
         switch ($p[0])
         {
            case 'mode':
               if(isAlpha($p[1]) && strlen($p[1]) < 3)
               {
                  if(strlen($p[1]) > 1)
                  {
                     if(substr($p[1], 1, 1) == '-')
                     {
                        $this->params['sort'] = " DESC";
                     } else
                     {
                        $this->params['sort'] = " ASC";
                     }
                  }
               }
               $p[1] = substr($p[1], 0, 1);
               $this->params['mode'] = in_array($p[1], $modes) ? $p[1] : 'i';
               break;

            case 'language':
               strtolower($p[1]);
               if(in_array($p[1], $this->MECCANO->system['lang'])) $this->params['language'] = $p[1];
               break;

            case 'user':
               isDigit($p[1]);
               $this->params['user'] = $p[1] != false ? $p[1] : 0;
               break;

            case 'search_length':
               isDigit($p[1]);
               $this->params['search_length'] = $p[1] != false ? $p[1] : 64;
               break;

            case 'hidden':
               if($p[1] != false) $this->params['hidden'] = true;
               break;
               
            case 'topsite':
               if($p[1] != false) $this->params['topsite'] = true;
               break;

            case 'indate':
               if($p[1] == true || $p[1] == 1 || $p[1] == 'yes') $this->params['indate'] = true;
               break;

            case 'count':
               if($p[1] == false || $p[1] == 0 || $p[1] = 'no') $this->params['count_views'] = false;
               break;
               
            case 'all_langs':
            case 'al':
               $this->params['all_langs'] = isBool($p[1]);
               break;
         }
      }

      return true;
   }


   /**
    * Get Info about table
    */
   function GetTable()
   {
      if($this->table !== null)
      {
         return $this->table;
      } else
      {
         $this->GetTableInfo();
         return $this->table;
      }
      return false;
   }
   /**
    * Get records
    *
    * @param integer $category
    * @return array
    */
   function Get($category = false)
   {
      if($this->property['table'] == false) return false;
      $sql    = '';
      $order  = '';
      $where  = '';
      $fields = false;


      // Make $order;

      switch ($this->params['mode'])
      {
         case 't':
            $order = ' ORDER BY BINARY maint.title';
            break;

         case 'd':
            $order = ' ORDER BY maint.dat';
            break;

         case 'k':
         case 's':
            $where[] = 'DATE_FORMAT(maint.dat, "%Y%m%d") = "' . date("Ymd", time()) . '"';
            $order   = ' ORDER BY RAND()';
            break;

         case 'c':
            $order = ' ORDER BY maint.cat';
            break;

         case 'r':
            $order = ' ORDER BY RAND()';
            break;

         case 'i':
         default:
            $order = ' ORDER BY maint.id';
      }


      $from[]   = $this->property['table'] . ' AS maint';
      
      // Make QUERY
      // Get FIELDS list
      if($this->table != false)
      {
         if(count($this->table['hidden']) > 0)
         {
            if(count($this->table['fields']) > 0)
            {
               $fields = array_merge($this->table['hidden'], $this->table['fields']);
            } else
            {
               $fields = $this->table['hidden'];
            }
         } elseif(count($this->table['fields']) > 0)
         {
            $fields = $this->table['fields'];
         }
      }
      
      if($fields != false)
      {
         // Selection just known fields with replacement of PROPERTIES
         foreach($fields AS $value)
         {
            if($value['property'] != 0)
            {
               $select[] = '(SELECT title FROM meccano_properties WHERE id = maint.' . $value['name'] . ') AS ' . $value['name'];
            } else
            {
               $select[] = 'maint.' . $value['name'];
            }
         }
      } else
      {
         // Direct selection
         $select[] = 'maint.*';
      }


      // TREE DEPENDENSIES
      if($this->property['treedepend'] != 0)
      {
         $select[] = 'trtrans.title AS category';
         $from[]   = 'meccano_treetranslates AS trtrans';
         $where[]  = 'maint.cat = trtrans.id';
         $where[]  = 'maint.lang = trtrans.lang';
         if($this->params['hidden'] === true) $where[] = 'maint.hidden = "1"';
         if($this->params['indate'] === true) $where[] = '(NOW() BETWEEN maint.dat AND maint.valid)';
      }
      
      // USER DEPENDENSIES
      if($this->property['userdepend'] != 0)
      {
         $select[] = 'usr.login AS login';
         $from[]   = 'meccano_users AS usr';
         $where[]  = 'maint.user = usr.id';
         if($this->params['user'] > 2) $where[] = 'maint.user = ' . $this->params['user'];
      }
      
      // IF TOPSITE ATTR NOT FALSE
      if($this->params['topsite'] != false)
      {
         $where[] = 'maint.topsite = "1"';
      }
      
      // JUST GIVEN LANGUAGE
      if($this->params['language'] != false)
      {
         $where[]  = 'maint.lang = "' . $this->params['language'] . '"';
      }
      
      // IDs of PARENT CATEGORIES
      if($category != false)
      {
         if(($list = $this->MECCANO->ListOfID($category)) != false)
         {
            $where[] = 'maint.cat IN (' . implode(',', $list) . ')';
         }
      }

      // COMPILE QUERY
      if($where != '') $where = ' WHERE ' . implode(' AND ', $where);

      $sql  = 'SELECT ' . implode(', ', $select);
      $sql .= ' FROM ' . implode(', ', $from);
      $sql .= $where . $order . $this->params['sort'];

      $this->DB->sql = $sql;
      $result = $this->DB->DB_Fetch();

      switch ($this->params['mode'])
      {
         case 'k':
            if($result == false)
            {
               $this->SetParams('mode=r');
               return $this->Get($category);
            }
            break;

         default:
            return $result;
      }
   }


   /**
    * View a record
    *
    * @param integer $id - Identifier of the deleted records
    * @param string  $condition - The field on which is carried out delete
    */
   function View($id, $condition = 'id')
   {
      if($this->property['table'] == false) return false;
      isAlpha($id);

      $sql = '';

      // MAKE QUERY
      $select[] = "maint.*";
      $from[]   = $this->property['table'] . " AS maint";
      if($id != false)
      {
         $where[]  = "maint." . $condition . " = '" . $id . "'";
      }

      if($this->property['treedepend'] != 0)
      {
         $select[] = "trtrans.title AS category";
         $from[]   = "meccano_treetranslates AS trtrans";
         $where[]  = "trtrans.id = maint.cat";
      }
      if($this->property['userdepend'] == 1)
      {
         $select[] = "usr.login AS login";
         $from[]   = "meccano_users AS usr";
         $where[]  = "maint.user = usr.id";
         if($this->params['user'] > 2) $where[] = "maint.user = " . $this->params['user'];
      }
      if($this->params['language'] != false)
      {
         $where[] = "maint.lang = '" . $this->params['language'] . "'";
         if($this->property['treedepend'] != 0) $where[] = "trtrans.lang = '" . $this->params['language'] . "'";
      } else
      {
         if($this->property['treedepend'] != 0) $where[] = 'trtrans.lang = "' . $this->params['default_lang'] . '"';
      }

      // COMPILE QUERY

      $sql  = "SELECT " . implode(", ", $select);
      $sql .= " FROM " . implode(", ", $from);
      $sql .= " WHERE " . implode(" AND ", $where);
      $sql .= ' LIMIT 0,1';

      $this->DB->sql = $sql;
      $result = $this->DB->DB_FetchFlat();

      if($this->params['count_views'] == true && isset($result['viewed']))
      {
         $this->DB->sql = "UPDATE " . $this->property['table'] . " SET viewed = viewed+1 WHERE id = '" . $id . "'";
         $this->DB->DB_Query();
      }

	   if($result != null)
	   {
		   $result['next'] = $this->Neighbor($result['id'], 'next');
		   $result['prev'] = $this->Neighbor($result['id'], 'prev');
	   }

      return $result;
   }

   function Images($category)
   {
      if(isDigit($category) == false || $this->property['gallery'] == false) return false;
      
      $sql = 'SELECT * FROM meccano_images WHERE mid = ' . $this->moduleid . ' AND cat = ' . $category;
      if($this->params['all_langs'] == false)
      {
         if($this->params['language'] != false) 
         {
            $sql .= ' AND lang = "' . $this->params['language'] . '"';
         } else
         {
            $sql .= ' AND lang = "' . $this->params['default_lang'] . '"';
         }
      }
      $sql .= ' ORDER BY';
      switch ($this->params['mode'])
      {
         case 't':
            $sql .= ' BINARY title ' . $this->params['sort'] . ', id, lang';
            break;

         case 'd':
            $sql .= ' dat ' . $this->params['sort'] . ', id, lang';
            break;

         case 'r':
            if($this->params['all_langs'] == false)
            {
               $sql .= ' RAND()';
               break;
            }

         case 'i':
         default:
            $sql .= ' id ' . $this->params['sort'] . ', lang';
      }
      
      $this->DB->sql = $sql;
      return $this->DB->DB_Fetch();
   }
   
   function Calendar($category)
   {
      if(isDigit($category) == false || $this->property['calendar'] == false) return false;
      
      $sql = 'SELECT * FROM meccano_calendar WHERE cat = ' . $category;
      if($this->params['all_langs'] == false)
      {
         if($this->params['language'] != false) 
         {
            $sql .= ' AND lang = "' . $this->params['language'] . '"';
         } else
         {
            $sql .= ' AND lang = "' . $this->params['default_lang'] . '"';
         }
      }
      $sql .= ' ORDER BY `begin` ' . $this->params['sort'] . ', `end` ' . $this->params['sort'];
      $this->DB->sql = $sql;
      $this->DB->DB_Fetch();
      return $this->DB->fetched;
   }
   /**
    * Get ID of Next|Previous entry of Datas conserning Sort Mode and parent category
    *
    * @param integer $cur_id ID of parent
    * @param strint $direction - can be next|prev
    * @return integer
    */
   function Neighbor($cur_id, $direction='next')
   {
      $sql =  'SELECT id FROM ' . $this->property['table'];
      if($this->params['sort'] == ' ASC' && $direction == 'next')
      {
         $comparator = '>';
         $order      = ' ASC';
      } elseif($this->params['sort'] == ' DESC' && $direction == 'next')
      {
         $comparator = '<';
         $order      = ' DESC';
      } elseif($this->params['sort'] == ' ASC' && $direction == 'prev')
      {
         $comparator = '<';
         $order      = ' DESC';
      } elseif($this->params['sort'] == ' DESC' && $direction == 'prev')
      {
         $comparator = '>';
         $order      = ' ASC';
      }

      switch ($this->params['mode'])
      {
         case 't':
            $sql .= ' WHERE title ' . $comparator . ' (SELECT title FROM ' . $this->property['table'] . ' WHERE id = ' . $cur_id . ' LIMIT 0,1)';
            if($this->property['treedepend'] != 0)
            {
               $sql .= ' AND cat = (SELECT cat FROM ' . $this->property['table'] . ' WHERE id = ' . $cur_id . ' LIMIT 0,1) ';
            }
            $sql .= 'ORDER BY title ' . $order . ' LIMIT 0 , 1 ';
            break;

         case 'd':
            $sql .= ' WHERE dat ' . $comparator . ' (SELECT dat FROM ' . $this->property['table'] . ' WHERE id = ' . $cur_id . ' LIMIT 0,1)';
            if($this->property['treedepend'] != 0)
            {
               $sql .= ' AND cat = (SELECT cat FROM ' . $this->property['table'] . ' WHERE id = ' . $cur_id . ' LIMIT 0,1) ';
            }
            $sql .= 'ORDER BY dat ' . $order . ' LIMIT 0 , 1 ';
            break;

         case 'c':
         case 'i':
            $sql .= ' WHERE id ' . $comparator . ' (SELECT id FROM ' . $this->property['table'] . ' WHERE id = ' . $cur_id . ' LIMIT 0,1)';
            if($this->property['treedepend'] != 0)
            {
               $sql .= ' AND cat = (SELECT cat FROM ' . $this->property['table'] . ' WHERE id = ' . $cur_id . ' LIMIT 0,1) ';
            }
            $sql .= 'ORDER BY id ' . $order . ' LIMIT 0 , 1 ';
            break;
            
         default:
            return false;
      }

      $this->DB->sql = $sql;
      $this->DB->DB_Fetch();

      if($this->DB->rows == 1)
      {
         return $this->DB->fetched[0]['id'];
      } else
      {
         return false;
      }
   }

   /**
    * Search
    *
    * @param string  $str
    * @param integer $cat
    * @param array   $params
    * @return array
    */
   function Search($str, $category = false, $params = false)
   {
      $str = prepare_str($str);
      isDigit($category, 'NOZERRO');
      if($str == false) return false;
      if($params == false) return false;

      $where  = '';
      $search = '';

      if(isset($params['fields']))
      {
         $params['fields'] = array_filter($params['fields'], "isAlpha");
      } else
      {
         return false;
      }

      if(isset($params['condition']))
      {
         foreach ($params['condition'] AS $value)
         {
            $cond = explode(':', $value);
            isAlpha($cond[0]);
            isAlpha($cond[2]);

            if($cond[0] != false && $cond[2] != false && in_array($cond[1], array('<','>','=')))
            {
               $where[] = "maint." . $cond[0] . " " . $cond[1] . " '" . $cond[2] . "'";
            }
         }
      }

      $str = substr($str, 0, $this->params['search_length']);
      $str = explode(" ", $str);

      foreach ($str as $value)
      {
         foreach ($params['fields'] as $field)
         {
            $search[] = "maint." . $field . " LIKE '%" . $value . "%'";
         }
      }

      $search = implode(' OR ', $search);

      // Make QUERY

      $select[] = "maint.*";
      $from[]   = $this->property['table'] . " AS maint";

      if($this->property['treedepend'] != 0)
      {
         $select[] = "trtrans.title AS category";
         $from[]   = "meccano_treetranslates AS trtrans";
         $where[]  = "maint.cat = trtrans.id";
         $where[]  = 'maint.lang = trtrans.lang';
      }
      if($this->property['userdepend'] != 0)
      {
         $select[] = "usr.login AS login";
         $from[]   = "meccano_users AS usr";
         $where[]  = "maint.user = usr.id";
      }
      if($this->params['language'] != false)
      {
         $where[]  = "maint.lang = '" . $this->params['language'] . "'";
         if($this->property['treedepend'] == 1) $where[] = "trtrans.lang = '" . $this->params['language'] . "'";
      }

      if($category != false)
      {
         if(($list = $this->MECCANO->ListOfID($category)) != false)
         {
            $where[] = "maint.cat IN (" . implode(',', $list) . ")";
         }
      }

      // COMPILE QUERY

      if($where != '')
      {
         $where = implode(" AND ", $where);
         $where = $where . " AND (" . $search . ")";
      } else
      {
         $where = $search;
      }

      $sql  = "SELECT " . implode(", ", $select);
      $sql .= " FROM " . implode(", ", $from);
      $sql .= " WHERE " . $where;

      $this->DB->sql = $sql;
      return $this->DB->DB_Fetch();
   }

   /**
    * Delete of records
    *
    * @param integer|array $id - Identifier of the deleted records
    * @param string        $condition - The field on which is carried out delete
    * @return bool
    */
   function Delete($id, $condition = 'id')
   {
      if(!isAlpha($condition)) return false;

      $del = array();
      if(is_array($id))
      {
         $del = array_filter($id, 'isDigit');
      } else
      {
         if(isDigit($id) != false) $del[] = $id;
      }
      unset($id);

      if(count($del) > 0)
      {
         $del = implode(',', $del);
         $sql = "DELETE FROM " . $this->property['table'] . " WHERE " . $condition . " IN (" . $del . ")";
         if($this->property['userdepend'] != 0 && $this->params['user'] > 2) $sql .= " AND user = " . $this->params['user'];

         $this->DB->sql = $sql;
         return $this->DB->DB_Query();
      }

      return false;
   }
   
   /**
    * Get Info about table
    * @param integer $mid
    * @return array|false
    */
   function GetTableInfo()
   {
      $this->DB->sql = 'SELECT * FROM meccano_tab_descr WHERE tid = ' . $this->moduleid . ' ORDER BY position ASC';
      $tableInfo = $this->DB->DB_Fetch();

      $table  = null;
      $Findex = 0;
      $Hindex = 0;
      $Lindex = 0;
      if($tableInfo != false)
      {
         for($i=0,$t=$this->DB->rows; $i<$t; $i++)
         {
            if($tableInfo[$i]['form'] == 'hidden')
            {
               $table['hidden'][$Hindex] = $tableInfo[$i];
               $Hindex++;
            } elseif($tableInfo[$i]['form'] != false)
            {
               $table['fields'][$Findex] = $tableInfo[$i];
               if($tableInfo[$i]['property'] != 0)
               {
                  $table['fields'][$Findex]['property'] = $this->GetProperty($tableInfo[$i]['property']);
               }
               $Findex++;
            }
            
            if($tableInfo[$i]['list'] == 1)
            {
               $table['list'][$Lindex] = $tableInfo[$i];
               $Lindex++;
            }
         }
         
         $table['params']['gallery']    = $this->property['gallery'];
         $table['params']['treedepend'] = $this->property['treedepend'];
         $table['params']['userdepend'] = $this->property['userdepend'];
         $table['params']['calendar']  = $this->property['calendar'];
      }

      $this->table = $table;
   }

   /**
    * Get list of properties
    *
    * @param integer $pid
    * @return array|false
    */
   function GetProperty($pid)
   {
      if(!isDigit($pid)) return false;
      $property = false;

      $this->DB->sql = 'SELECT * FROM meccano_property WHERE id = ' . $pid;
      $property = $this->DB->DB_FetchFlat();
      if($property)
      {
         $this->DB->sql = 'SELECT id, title FROM meccano_properties WHERE pid = ' . $pid . ' AND lang = "' . $this->params['language'] . '"';
         $property['list'] = $this->DB->DB_Fetch();
      }
      return $property;
   }
}


/**
 * Make compatibility for PHP4 and PHP5 overload methods
 */
if (phpversion() >= 5)
{
    eval('class kernel extends Kernel_PHP5 {
        function __call($method, $params) {
            return $this->__call__($method, $params);
        }
    }');
}
else
{
    eval('class kernel extends Kernel_PHP4 {
        function __call($method, $params, &$return) {
            $return = $this->__call__($method, $params);
            return true;
        }
    }');
}